/*
 *
 * Copyright 2011-2012 University of Illinois
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

Components.utils.import("resource://oaa-cache-inspector/cache-inspector-common.js");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");



/**
 * @function preferencesDialog
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Opens the preferences dialog box
 */

OAA_CI_UTILS.preferencesDialog = function () {

  window.openDialog('chrome://oaa-cache-inspector/content/preferences/preferences-dialog.xul', "_cache_inspector_preferences_dialog"); 

};

/**
 * @function exportRules
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Opens the preferences dialog box
 */

OAA_CI_UTILS.exportRules = function () {

  var dir = FileUtils.getDir('Desk', ['OAA Rules'], true, true);

  var file = FileUtils.getFile('Desk', ['OAA Rules', 'oaa_exported_rules.html']);
  
  var fileStream = FileUtils.openSafeFileOutputStream(file, 0x02 | 0x08 | 0x20, 0644, 0);  
  
  var title = 'Exported OAA Rule and Ruleset Information';
  
  var html = "";
  html += "<!DOCTYPE html>";
  html += "<html lang='en-us'>\n";
  html += "  <head>\n";
  html += "    <title id='ID_TITLE'>" + title + "</title>\n";
  html += "    <script type='text/javascript'>\n";
  html += "      wcag20 = " + OpenAjax.a11y.all_wcag20_nls.nls['en-us'].toJSON("\n      ") + ";\n";
  html += "      rules = " + OpenAjax.a11y.all_rules.toJSON("      ");
  html += "      rulesets = " + OpenAjax.a11y.all_rulesets.toJSON("      ");
  html += "    </script>\n";
  html += OpenAjax.a11y.rule_export_js;
  html += OpenAjax.a11y.rule_export_css;
  html += "  </head>\n";
  html += OpenAjax.a11y.rule_export_body;
  html += "</html>\n";
  
  fileStream.write(html, html.length);
  
  FileUtils.closeSafeFileOutputStream(fileStream);
    
  OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("Report URL: " + file.path);
  
  var interface1 = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  var interface2 = interface1.getInterface(Components.interfaces.nsIWebNavigation);
  var interface3 = interface2.QueryInterface(Components.interfaces.nsIDocShellTreeItem);
  var interface4 = interface3.rootTreeItem.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  var mainWindow = interface4.getInterface(Components.interfaces.nsIDOMWindow);
 
  if (mainWindow) mainWindow.gBrowser.addTab(file.path);

};

/**
 * @function exportEvaluation
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Opens the preferences dialog box
 */

OAA_CI_UTILS.exportEvaluation = function () {

  var dir = FileUtils.getDir('TmpD', [], true, true);

  var file = FileUtils.getFile('TmpD', ['oaa_report_evaluation.py']);
  
  var fileStream = FileUtils.openSafeFileOutputStream(file, 0x02 | 0x08 | 0x20, 0644, 0);  
    
  var doc;
  var title;
  var url;

  try {
      doc = window.content.document;
      title = doc.title;
      url = window.content.location.href;
  } catch(e) {
      doc  = window.opener.parent.content.document;
      title = doc.title;
      url = window.opener.parent.location.href;
  } // end try
  
  var prefs = OAA_WEB_ACCESSIBILITY_PREF.util.getPreferences();
 
  var ruleset = OpenAjax.a11y.all_rulesets.getRuleset(prefs.ruleset_id); 

  var python_code = "Ruleset not initialized\n";  

  if (ruleset) {

    ruleset.setEvaluationLevel(prefs.wcag20_level);
    ruleset.setRecommendedRulesEnabled(prefs.wcag20_recommended_rules_enabled);
    ruleset.setBrokenLinkTesting(prefs.broken_links);
  
    OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("Preforming Evaluation: " + title + " " + url);
    OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("    Ruleset ID: " + ruleset.ruleset_id);
    OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("    WCAG Level: " + ruleset.wcag20_level);
    OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("  Broken Links: " + OpenAjax.a11y.URL_TESTING_ENABLED);

    ruleset.evaluate(url, title, doc, null, true);
    
    var python_code = ruleset.exportEvaluationResultsToPython();   

  }
    
    
  fileStream.write(python_code, python_code.length);
  
  FileUtils.closeSafeFileOutputStream(fileStream);
    
  OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("Evaluation Report URL: " + file.path);
  
  var interface1 = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  var interface2 = interface1.getInterface(Components.interfaces.nsIWebNavigation);
  var interface3 = interface2.QueryInterface(Components.interfaces.nsIDocShellTreeItem);
  var interface4 = interface3.rootTreeItem.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  var mainWindow = interface4.getInterface(Components.interfaces.nsIDOMWindow);
 
  if (mainWindow) mainWindow.gBrowser.addTab(file.path);

};

/**
 * @function sidebarOpenLast
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Initialize OAA Sidebar for viewing images cache
 */

OAA_CI_UTILS.sidebarOpenLast = function () {

  var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  .getInterface(Components.interfaces.nsIWebNavigation)
  .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
  .rootTreeItem
  .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  .getInterface(Components.interfaces.nsIDOMWindow);

  if (typeof mainWindow.oaa_sidebar_name === 'string' && mainWindow.oaa_sidebar_name.length ) {
    OAA_CI_UTILS.sidebarCommon(mainWindow.oaa_sidebar_name, mainWindow.oaa_option, mainWindow.oaa_sidebar_type, mainWindow.oaa_sidebar_id);
  }
  else {
    OAA_CI_UTILS.showRuleSummary('WCAG20');
  }
  
};

/**
 * @function showRuleCategory
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Initialize OAA Sidebar for viewing audio/video cache
 */

OAA_CI_UTILS.showRuleCategory = function (id) {

  switch (id) {
  
  case 'ALL':
     OAA_CI_UTILS.sidebarCommon('All Rules', OpenAjax.a11y.RULE_CATEGORIES.ALL, 'category', id);
     break;

  case 'STRUCTURE':
     OAA_CI_UTILS.sidebarCommon('Structure Rules', OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE, 'category', id);
     break;

  case 'STYLES':
     OAA_CI_UTILS.sidebarCommon('Style Rules', OpenAjax.a11y.RULE_CATEGORIES.STYLES, 'category', id);
     break;

  case 'IMAGES':
     OAA_CI_UTILS.sidebarCommon('Image Rules', OpenAjax.a11y.RULE_CATEGORIES.IMAGES, 'category', id);
     break;

  case 'TABLES':
     OAA_CI_UTILS.sidebarCommon('Data Table Rules', OpenAjax.a11y.RULE_CATEGORIES.TABLES, 'category', id);
     break;

  case 'LINKS':
     OAA_CI_UTILS.sidebarCommon('Link Rules', OpenAjax.a11y.RULE_CATEGORIES.LINKS, 'category', id);
     break;

  case 'FORM_CONTROLS':
     OAA_CI_UTILS.sidebarCommon('Form Controls', OpenAjax.a11y.RULE_CATEGORIES.CONTROLS, 'category', id);
     break;

  case 'WIDGETS':
     OAA_CI_UTILS.sidebarCommon('Widget Rules', OpenAjax.a11y.RULE_CATEGORIES.WIDGETS, 'category', id);
     break;

  case 'AUDIO_VIDEO':
     OAA_CI_UTILS.sidebarCommon('Audio/Video Rules', OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO, 'category', id);
     break;

  case 'LAYOUT':
     OAA_CI_UTILS.sidebarCommon('Layout/Order Rules', OpenAjax.a11y.RULE_CATEGORIES.LAYOUT, 'category', id);
     break;

  case 'TIMING':
     OAA_CI_UTILS.sidebarCommon('Timing Rules', OpenAjax.a11y.RULE_CATEGORIES.TIMING, 'category', id);
     break;

  default:
     break;

  }
};

/**
 * @function showRuleSummary
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Initialize OAA Sidebar for view a rule summary
 */

OAA_CI_UTILS.showRuleSummary = function (id) {

  switch (id) {

  case 'TRIAGE':
     OAA_CI_UTILS.sidebarCommon('Triage Rules', OpenAjax.a11y.RULE_SUMMARY.TRIAGE, 'summary', id);
     break;

  case 'CATEGORIES':
     OAA_CI_UTILS.sidebarCommon('Rules by Rule Categories', OpenAjax.a11y.RULE_SUMMARY.CATEGORIES, 'summary', id);
     break;

  case 'WCAG20':
     OAA_CI_UTILS.sidebarCommon('Rules by WCAG 2.0', OpenAjax.a11y.RULE_SUMMARY.WCAG20, 'summary', id);
     break;

  default:
     break;

  }
};



/**
 * @function showElementType
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Initialize OAA Sidebar for viewing audio/video cache
 */

OAA_CI_UTILS.showElementType = function (id) {

  switch (id) {
  
  case 'ALL':
     OAA_CI_UTILS.sidebarCommon('All Elements', OpenAjax.a11y.ELEMENT_TYPE.ALL, 'element', id);
     break;

  case 'AUDIO_VIDEO':
     OAA_CI_UTILS.sidebarCommon('Audio/Video Elements', OpenAjax.a11y.ELEMENT_TYPE.AUDIO_VIDEO, 'element', id);
     break;

  case 'HEADINGS_LANDMARKS':
     OAA_CI_UTILS.sidebarCommon('Headings/Landmarks Elements', OpenAjax.a11y.ELEMENT_TYPE.HEADINGS_LANDMARKS, 'element', id);
     break;

  case 'IMAGES':
     OAA_CI_UTILS.sidebarCommon('Image Elements', OpenAjax.a11y.ELEMENT_TYPE.IMAGES, 'element', id);
     break;

  case 'FORM_CONTROLS':
     OAA_CI_UTILS.sidebarCommon('Form Control Elements', OpenAjax.a11y.ELEMENT_TYPE.FORM_CONTROLS, 'element', id);
     break;

  case 'LINKS':
     OAA_CI_UTILS.sidebarCommon('Link Elements', OpenAjax.a11y.ELEMENT_TYPE.LINKS, 'element', id);
     break;

  case 'TABLES':
     OAA_CI_UTILS.sidebarCommon('Table Elements', OpenAjax.a11y.ELEMENT_TYPE.LAYOUT_TABLES, 'element', id);
     break;

  case 'TEXT':
     OAA_CI_UTILS.sidebarCommon('Text Elements', OpenAjax.a11y.ELEMENT_TYPE.TEXT, 'element', id);
     break;

  case 'WIDGETS':
     OAA_CI_UTILS.sidebarCommon('Widget Elements', OpenAjax.a11y.ELEMENT_TYPE.WIDGETS, 'element', id);
     break;

  default:
     break;

  }
  
};


/**
 * @function sidebarCommon
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Toggle the sidebar based on the ID of the corresponding toolbarbutton
 *
 * @param {String}   name     - name of view
 * @param {Number}   option   - Constant representing the option for the view (i.e. rule category constant)
 * @param {String}   type     - type of cache to view
 * @param {String}   id       - id to update the toolbars and menu
 */

OAA_CI_UTILS.sidebarCommon = function (name, option, type, id) {

  var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  .getInterface(Components.interfaces.nsIWebNavigation)
  .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
  .rootTreeItem
  .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  .getInterface(Components.interfaces.nsIDOMWindow);

  if (!name || name.length === 0) return;

  mainWindow.oaa_sidebar_name    = name;
  mainWindow.oaa_sidebar_option  = option;
  mainWindow.oaa_sidebar_type    = type;
  mainWindow.oaa_sidebar_id      = id;
  
  var toolbarbutton_id = "";
  var menuitem_id = "";
  
  if (type === 'element') {
    toolbarbutton_id   = "ID_TOOLBARBUTTON_ELEMENT_TYPE_" + id;
    menuitem_id  = "ID_MENUITEM_ELEMENT_TYPE_" + id;
  }
  else {
    if (type === 'category') {
      toolbarbutton_id   = "ID_TOOLBARBUTTON_RULE_CATEGORY_" + id;
      menuitem_id  = "ID_MENUITEM_RULE_CATEGORY_" + id;
    }
    else {
      toolbarbutton_id   = "ID_TOOLBARBUTTON_RULE_SUMMARY_" + id;
      menuitem_id  = "ID_MENUITEM_RULE_SUMMARY_" + id;    
    }
  }
        
  OAA_CI_UTILS.setStateToolbarAndMenus(mainWindow, toolbarbutton_id, menuitem_id);
  
  var sidebar_open = false;
  var sidebarWindow = document.getElementById("sidebar").contentWindow;
  
  // Verify that our sidebar is open at this moment:
  if (sidebarWindow && sidebarWindow.location.href ==
      "chrome://oaa-cache-inspector/content/sidebar.xul") {
      sidebar_open = true;
  } 

  if (typeof mainWindow.oaa_sidebar_last_name === 'string' && mainWindow.oaa_sidebar_last_name == name) {
    toggleSidebar('ID_SIDEBAR_OAA_CACHE_INSPECTOR');
  }
  else {
    if (sidebar_open) {
      sidebarWindow.OAA_CI.initSidebar(type);
      sidebarWindow.OAA_CI.updateSidebar();
    } 
    else {
      toggleSidebar('ID_SIDEBAR_OAA_CACHE_INSPECTOR');
    }  
  }

  mainWindow.oaa_sidebar_last_name = name;
    
};

/**
 * @function setFocusSummary
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Move keyboard focus to the summary list in the OAA sidebar 
 */
 
OAA_CI_UTILS.setFocusSummary = function() {

  var node_focus = null;

  var sidebarWindow = window.document.getElementById("sidebar").contentWindow;
  
//  OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("side bar window: " + sidebarWindow);

  if (sidebarWindow) {
  
    var vbox_rule_summary    = sidebarWindow.document.getElementById('ID_VBOX_RULE_SUMMARY_VIEW');  
    var vbox_rule_category   = sidebarWindow.document.getElementById('ID_VBOX_RULE_CATEGORY_VIEW');  
    var vbox_element         = sidebarWindow.document.getElementById('ID_VBOX_ELEMENT_VIEW');  

    if (vbox_rule_summary  && !vbox_rule_summary.hidden)  node_focus = sidebarWindow.document.getElementById('ID_TREE_RULE_SUMMARY');
    if (vbox_rule_category && !vbox_rule_category.hidden) node_focus = sidebarWindow.document.getElementById('ID_LISTBOX_RULE_CATEGORY_VIEW');      
    if (vbox_element       && !vbox_element.hidden)       node_focus = sidebarWindow.document.getElementById('ID_TREE_ELEMENT_VIEW_ITEMS');
      
    if (node_focus) node_focus.focus();

  }  

};

/**
 * @function openReport
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Open a OAA report for a view 
 */
 
OAA_CI_UTILS.openReport = function() {

  var node_focus = null;

  var sidebarWindow = window.document.getElementById("sidebar").contentWindow;
  
//  OAA_WEB_ACCESSIBILITY_LOGGING.logger.log.debug("side bar window: " + sidebarWindow);

  if (sidebarWindow) {
  
    var vbox_rule_summary  = sidebarWindow.document.getElementById('ID_VBOX_RULE_SUMMARY_VIEW');  
    var vbox_rule_category   = sidebarWindow.document.getElementById('ID_VBOX_RULE_CATEGORY_VIEW');  
    var vbox_element        = sidebarWindow.document.getElementById('ID_VBOX_ELEMENT_VIEW');  

    if (vbox_rule_summary  && !vbox_rule_summary.hidden)  sidebarWindow.OAA_CI.RuleSummaryView.showRuleSummaryReport();
    if (vbox_rule_category && !vbox_rule_category.hidden) sidebarWindow.OAA_CI.RuleCategoryView.showRuleCategoryReport();      
    if (vbox_element       && !vbox_element.hidden)       sidebarWindow.OAA_CI.ElementView.showCacheItemReport(); 
      
  }  

};


/**
 * @function setFocusDetails
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Move keyboard focus to the summary list in the OAA sidebar 
 */

OAA_CI_UTILS.setFocusDetails = function() {

  var node_focus = null;

  var sidebarWindow = window.document.getElementById("sidebar").contentWindow;
  
  if (sidebarWindow) {
  
    var vbox_rule_result    = sidebarWindow.document.getElementById('ID_VBOX_RULE_RESULT_VIEW');  
    var vbox_element_result = sidebarWindow.document.getElementById('ID_VBOX_ELEMENT_RESULT_VIEW');  

    if (vbox_rule_result    && !vbox_rule_result.hidden)    node_focus = sidebarWindow.document.getElementById('ID_TREE_RULE_RESULT_LIST');
    if (vbox_element_result && !vbox_element_result.hidden) node_focus = sidebarWindow.document.getElementById('ID_TREE_ELEMENT_RESULT_VIEW');

    if (node_focus) node_focus.focus();
    
  }  
};


/** 
 * @function showAbout
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc shows the log information for the last evaluation
 *
 * @param {String}  format  - String format of the the log file, valid values TEXT, XML, JSON and HTML
 */

OAA_CI_UTILS.showAbout = function() {

  window.open("chrome://oaa-cache-inspector/content/about.xul", "aboutDialog", "chrome,centerscreen");
  
};

/**
 * @function onLoad
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc onload function sets toolbar and menu visibility
 */

OAA_CI_UTILS.onLoad = function () {
  
  function getButtonFromPalette() {
  
    var palette = gNavToolbox.palette;
    for (var i = 0; i < palette.childNodes.length; ++i) {
      var child = palette.childNodes[i];
      if (child.id && child.id == ID_BUTTON) return child;
    }
    return null;
  }

  var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  .getInterface(Components.interfaces.nsIWebNavigation)
  .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
  .rootTreeItem
  .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  .getInterface(Components.interfaces.nsIDOMWindow);

  mainWindow.oaa_sidebar_last_name    = "";
  mainWindow.oaa_sidebar_option       = "";
  mainWindow.oaa_sidebar_type         = null;

  mainWindow.oaa_sidebar_last_toolbarbutton_id = "";
  mainWindow.oaa_sidebar_last_menuitem_id      = "";
  
  var prefs = OAA_WEB_ACCESSIBILITY_PREF.util.getPreferences();

  var ID_BUTTON = 'ID_TOOLBAR_PALETTE_ICON';
  var ID_TOOLBAR = 'addon-bar';
  var toolbar = document.getElementById(ID_TOOLBAR);  

  if (toolbar) {
    var button = getButtonFromPalette();
    
    if (button && prefs.show_accessibility_icon) {
      toolbar.insertItem(ID_BUTTON, null, null, false);
      toolbar.collapsed = false;    
    }
    
    button = document.getElementById(ID_BUTTON);
    
    if (button) {
      if (prefs.show_accessibility_icon) button.setAttribute('hidden', 'false');
      else button.setAttribute('hidden', 'true');
    }
    
  } 

 // Use user preferences to enable the accessibility menu

  var menu = document.getElementById('ID_MENU_OAA_CACHE_INSPECTOR');
  
  if (menu && prefs.show_accessibility_menu) {
    menu.setAttribute('hidden', 'false');
  } 
  
  // Make sure the sidebar does not open in new windows
  
  var sidebar_id = "chrome://oaa-cache-inspector/content/sidebar.xul";
  
  var sidebarWindow = document.getElementById("sidebar").contentWindow;
  // Verify that our sidebar is open at this moment:
  if (sidebarWindow && sidebarWindow.location.href == sidebar_id) {
     toggleSidebar(sidebar_id);
  } 
  
};

/**
 * @function unLoad
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc onload function sets toolbar and menu visibility
 */

OAA_CI_UTILS.onUnload = function () {

};


/**
 * @function onFocus
 *
 * @memberOf OAA_CI_UTILS
 *
 * @desc Update window reference when a window get focus
 */


window.addEventListener("load",   function () { OAA_CI_UTILS.onLoad();   }, false);
window.addEventListener("unload", function () { OAA_CI_UTILS.onUnload(); }, false);
